package com.feng
{
	import com.feng.behavior.AttackBehavior;
	import com.feng.behavior.BehaviorCompute;
	import com.feng.behavior.BehaviorControler;
	import com.feng.behavior.DefenseBehavior;
	import com.feng.data.StateData;
	import com.feng.debug.logger1;
	import com.feng.stateAnalysis.AttackMaxAnalysis;
	import com.feng.stateAnalysis.AttackOrderAnalysis;
	import com.feng.stateAnalysis.ThreeAnalysis;
	import com.feng.strategy.StrategyManager;

	/**
	 * 控制中心
	 * @author 风之守望者
	 * 2013-3-29
	 */
	public class ControllerCenter
	{
		/** 当前状态的数据 */
		public var stateData:StateData;

		/** 攻击行为 */
		public var attackBehavior:AttackBehavior;

		/** 防御行为 */
		public var defenseBehavior:DefenseBehavior;

		/** 行为控制中心 */
		public var behaviorControler:BehaviorControler;

		/** 策略管理 */
		public var strategyManager:StrategyManager;

		/** 行为计算 */
		public var behaviorCompute:BehaviorCompute;

		/** 三人模式下形势分析 */
		public var threeStateAnalysis:ThreeAnalysis;

		/** 攻击顺序分析 */
		public var attackOrderAnalysis:AttackOrderAnalysis;

		public var attackMaxAnalysis:AttackMaxAnalysis;

		public function ControllerCenter()
		{
			//初始化数据
			stateData = new StateData();

			//初始化行为
			attackBehavior = new AttackBehavior(stateData);
			defenseBehavior = new DefenseBehavior(stateData);
			behaviorControler = new BehaviorControler(this);

			//初始化策略
			strategyManager = new StrategyManager(this);

			//初始化形势分析
			threeStateAnalysis = new ThreeAnalysis(stateData);

			attackOrderAnalysis = new AttackOrderAnalysis(stateData);

			attackMaxAnalysis = new AttackMaxAnalysis(stateData);

			//初始化 最终行为计算
			behaviorCompute = new BehaviorCompute(this);
		}

		/**
		 *  //轮到你行动时会被调用。
		 //在一场战斗中，你已经死亡或者已经胜利不会继续被调用。
		 //参数state，返回所有程序员的状态，格式如[{id:0,hp:150,atk:20,def:0,spd:10},{id:1,hp:170,atk:12,def:12,spd:10}, ...]。
		 //在一次战斗中，state中玩家的顺序不改变，死人会以hp=0的状态存在state里。顺序序号始终等于数组中的id值。
		 //参数myId，我的id，自己是数组中的第几位。
		 //返回值：一个整形。你要攻击的目标序号。
		 //返回自己、返回已经空血的人、返回不存在的序号都视为攻击自己。
		 */
		public function onAttack(state:Array, myId:int):int
		{
			logger1(JSON.stringify(["onAttack", state, myId]));
			
			stateData.onAttack(state, myId);

			//选择合适的策略
			strategyManager.selectStrategy();

			//初始化攻击策略
			strategyManager.initAttackStrategy();

			var attackId:int = behaviorCompute.getAttackId();

			return attackId;
		}

		/**
		 * 	//在你升级时会被调用。前两参数同上。第三参数表示这是否是因为击杀而获得的升级奖励
		 //在一场战斗中，你已经死亡或者已经胜利不会继续被调用。
		 //isKillUpgrade表示是否是击杀升级。击杀升级时，会先增加50点hp，之后再调用这个函数。
		 //返回值：一个整形。
		 //返回4：提高4点攻击
		 //返回3：提高3点防守
		 //返回2：提高2点速度
		 //返回1：提高1点三围（三种属性）
		 //返回其他值视为放弃这次升级。
		 **/
		public function onUpgrade(state:Array, myId:int, isKillUpgrade:Boolean):int
		{
			logger1(JSON.stringify(["onUpgrade", state, myId, isKillUpgrade]));

			//更新数据
			stateData.onUpgrade(state, myId, isKillUpgrade);

			//选择合适的策略
			strategyManager.selectStrategy();

			//初始化防御策略
			strategyManager.initDefenseStrategy();

			var upgradeId:int = behaviorCompute.getUpgradeId();

			return upgradeId;
		}

		//每当有人发动攻击时被调用，包括自己的攻击。state是攻击前的状态
		//收集数据可能对连续战斗的下一场有用，即使你已经挂掉了，也会被触发。
		//参数attcker，攻击的发动者。
		//参数target，攻击的承受者。
		public function onAnyoneAttack(state:Array, myId:int, attackerId:int, targetId:int):void
		{
			logger1(JSON.stringify(["onAnyoneAttack", state, myId, attackerId, targetId]));
			
			attackOrderAnalysis.onAnyoneAttack(state, myId, attackerId, targetId);
			
			stateData.onAnyoneAttack(state, myId, attackerId, targetId);
			
			attackMaxAnalysis.onAnyoneAttack(state, myId, attackerId, targetId);

		}

		//每当有人升级时被调用，包括自己的升级。state是升级前的状态。
		//收集数据可能对连续战斗的下一场有用，即使你已经挂掉了，也会被触发。
		//isKillUpgrade表示是否是击杀升级。击杀升级时，会先增加50点hp，之后再调用这个函数。
		//如果有人放弃了升级（会有吗？），upgradeType可能是1~4之外的数字。
		public function onAnyoneUpgrade(state:Array, myId:int, upgraderId:int, upgradeType:int):void
		{
			logger1(JSON.stringify(["onAnyoneUpgrade", state, myId, upgraderId, upgradeType]));

			stateData.onAnyoneUpgrade(state, myId, upgraderId, upgradeType);
		}

		//通知一场战斗开始
		//在连续战斗测胜率的过程中，不会重新加载swf，所以可以在这里初始化一些变量。
		//在此时，你的id会重新分配。
		public function onBattleStart(myId:int):void
		{
			FengData.showDataIndex = 0;
			logger1(JSON.stringify(["onBattleStart", myId]));
			
			stateData.onBattleStart(myId);

			attackMaxAnalysis.onBattleStart(myId);
		}

		//通知一场战斗结束
		//收集数据可能对连续战斗的下一场有用，即使你已经挂掉了，也会被触发。
		//为避免大家群殴胜率最高者导致胜率难以区分，这个函数的参数不会提供“谁是胜者”
		//参数totalBattles, 总计连续进行的战斗次数。
		//参数myVectories, 自己的胜场。
		public function onBattleFinish(totalBattles:int, myVectories:int):void
		{
			logger1(JSON.stringify(["onBattleFinish", totalBattles, myVectories]));
			
			attackMaxAnalysis.onBattleFinish(totalBattles, myVectories);
		}

		//通知回合开始。
		//收集数据可能对连续战斗的下一场有用，即使你已经挂掉了，也会被触发。
		public function onTurn(state:Array, myId:int):void
		{
			logger1(JSON.stringify(["onTurn", state, myId]));
			
			stateData.onTurn(state, myId);

			attackOrderAnalysis.onTurn(state, myId);
		}

		//游戏开始时仅会被调用一次
		//gameMode是游戏模式（局数），players是有多少玩家参与游戏。
		public function onGameSet(gameMode:int, players:int):void
		{
			logger1("clear");
			logger1(JSON.stringify(["onGameSet", gameMode, players]));
		}

		//在每局开始时或有玩家阵亡导致玩家人数改变时被调用。
		//在多局游戏中，这个方法能让玩家大致了解正在与哪些对手作战。
		//livingMD5：仍生存玩家文件名的MD5值。
		//livingMD5的顺序并非与id一一对应，而是打乱的！因此你只能知道还有哪些人活着而不能知道他们的座次。
		//myMD5：我的文件名加密后的MD5值
		public function onPlayerNumChanged(state:Object, myId:int, livingMD5:Array, myMD5:String):void
		{
			logger1(JSON.stringify(["onPlayerNumChanged", state, myId, livingMD5, myMD5]));
		}
	}
}
